package subprocess

import (
	"encoding/json"
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/orm"
	"playbook/ginsvr/src/source/gene"
	"playbook/ginsvr/src/utils/fileutil"
	"playbook/ginsvr/src/utils/httputil"
	"playbook/ginsvr/src/utils/netutil"
	"strings"

	"github.com/sirupsen/logrus"
)

/**
*  子流程复制
*  oldname：原子流程名称
*  name：新子流程名称
*  desc：新子流程描述
*  overtime： 新子流程超时时间
*  version： 新子流程版本
*  type: 0-子流程 1-编排
 */
func CopySubProcess(param map[string]interface{}) orm.Response {
	if param["name"] == nil || param["overtime"] == nil || param["version"] == nil || param["type"] == nil {
		return orm.Response{
			RespCode: "000001",
			RespMsg:  "子流程保存失败,参数不完整",
		}
	}
	//1.数据库新增数据
	//查询原子流程或编排信息
	var process orm.Process
	if param["type"].(string) == "0" {
		old := *orm.GetSubProcess(param["oldname"].(string))
		process = (old).SubProcess
	} else if param["type"].(string) == "1" {
		old := *orm.GetProcess(param["oldname"].(string))
		process = (old).Process
	} else {
		return orm.Response{
			RespCode: "000001",
			RespMsg:  "子流程保存失败,类型信息错误",
		}
	}

	if param["name"] != nil {
		process.Name = param["name"].(string)
	}
	if param["desc"] != nil {
		process.Desc = param["desc"].(string)
	}
	if param["overtime"] != nil {
		process.Overtime = param["overtime"].(string)
	}
	if param["version"] != nil {
		process.Version = param["version"].(string)
	}
	data, _ := json.Marshal(&process)
	json.Unmarshal(data, &process)

	//数据库中新增子编排
	fullSubProcess := orm.FullSubProcess{SubProcess: process}
	res := orm.AddSubprocess(fullSubProcess)
	switch res.(type) {
	case error:
		return orm.Response{RespCode: "000001",
			RespMsg: "子流程保存失败，数据库新增失败"}
	case orm.Response:
		return orm.Response{RespCode: "000001",
			RespMsg: "子流程保存失败，数据库新增失败"}
	}

	//生成编排出入参类
	geneParamBean("subprocessbean", process.Name,
		orm.GenebeanParammsg{
			Inparamid:  process.Inputparamid,
			Outparamid: process.Outputparamid,
			Subpath:    "",
		})

	//子流程json保存
	SaveSubProcess(fullSubProcess)

	//处理脚本和循环
	for _, i := range process.Activities["activity"] {
		acti := i.(map[string]interface{})
		//如果是循环或脚本
		if acti["type"] == float64(1) {
			var inputparamid string
			var outputparamid string
			//入参不为空，取入参ID
			if acti["input-parameter"] != nil && acti["input-parameter"].(map[string]interface{})["parameter"] != nil &&
				acti["input-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})["name"] != nil {
				temp := acti["input-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})["name"].(string)
				p, _ := orm.GetParamByName(temp)
				inputparamid = p.Parameterid
			}
			//出参不为空，取出参ID
			if acti["output-parameter"] != nil && acti["output-parameter"].(map[string]interface{})["parameter"] != nil &&
				acti["output-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})["name"] != nil {
				temp := acti["output-parameter"].(map[string]interface{})["parameter"].(map[string]interface{})["name"].(string)
				p, _ := orm.GetParamByName(temp)
				outputparamid = p.Parameterid
			}
			//生成循环出入参
			geneParamBean("composebean", process.Name, orm.GenebeanParammsg{
				Inparamid:  inputparamid,
				Outparamid: outputparamid,
				Subpath:    acti["name"].(string),
			})

			//如果是脚本，复制脚本代码和出入参
		} else if acti["type"] == float64(2) {
			newfiles := getScriptPath(process.Name + "." + acti["name"].(string))
			oldfiles := getScriptPath(param["oldname"].(string) + "." + acti["name"].(string))
			if len(newfiles) > 0 {
				//本地复制脚本类文件和出参文件
				fileutil.CopyFile(newfiles[0], oldfiles[0])
				fileutil.CopyFile(newfiles[1], oldfiles[1])
				ip, err := netutil.ExternalIP()
				if err != nil {
					global.LOG.WithFields(logrus.Fields{
						"err": err,
					}).Error("子流程保存失败,获取本地IP失败")
					return orm.Response{RespCode: "000001",
						RespMsg: "子流程保存失败,获取本地IP失败"}
				}
				//服务器复制脚本类文件和出参文件
				err = httputil.ScriptCopy(httputil.CopyContent{IP: ip.String(),
					Newpath: newfiles,
					Oldpath: oldfiles})
				if err != nil {
					global.LOG.WithFields(logrus.Fields{
						"err": err,
					}).Error("子流程保存失败,服务器脚本复制失败.")
					return orm.Response{RespCode: "000001",
						RespMsg: "子流程保存失败,服务器脚本复制失败"}
				}
			}

		}

	}
	return orm.Response{RespCode: "000000",
		RespMsg: "子流程保存成功"}
}

/**
* 保存子流程json文件
 */
func SaveSubProcess(fullSubProcess orm.FullSubProcess) {
	processJson, _ := json.MarshalIndent(fullSubProcess, "", "\t")
	srcpath := orm.GetGeneSrcDefine("subprocessjson").Srcpath

	createDirPath := srcpath + global.PTHSEP + fullSubProcess.SubProcess.Name
	standardName := fullSubProcess.SubProcess.Name + ".json"
	fileutil.GetClearFile(createDirPath, standardName)

	standardJsonPath := srcpath + global.PTHSEP + fullSubProcess.SubProcess.Name + global.PTHSEP + fullSubProcess.SubProcess.Name + ".json"
	var strlstStandard []string
	strlstStandard = append(strlstStandard, string(processJson))

	fileutil.Filewrite(standardJsonPath, strlstStandard)
}

/**
* 获取脚本文件路径
 */
func getScriptPath(actname string) []string {

	gsd := orm.GetGeneSrcDefine("script")
	if gsd.Srcpath == "" {
		return []string{}
	}

	snlst := strings.Split(actname, ".")
	srcpath := fileutil.SepTransform(gsd.Srcpath + global.PTHSEP + strings.TrimSpace(snlst[0]))

	return []string{srcpath + global.PTHSEP + snlst[1] + ".java", srcpath + global.PTHSEP + snlst[1] + "Out.java"}
}

/**
*  生成出入参文件
 */
func geneParamBean(genetype string, pname string, genebeanmsg orm.GenebeanParammsg) {

	if genebeanmsg.Inparamid != "" {
		gene.GeneParamBean(genetype, pname, genebeanmsg.Inparamid, genebeanmsg.Subpath)
	}
	if genebeanmsg.Outparamid != "" {
		gene.GeneParamBean(genetype, pname, genebeanmsg.Outparamid, genebeanmsg.Subpath)
	}

}
